package com.ck.framework.config;

import com.ck.common.utils.txt.TextUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;


/**
 * @author ck
 */
@Slf4j
@Configuration
public class OkHttpConfig {

    @Value("${application.http-timeout:5}")
    private Integer timeout;


    /**
     * 生成HTTP链接客户端对象
     *
     * @return
     */
    @Bean
    public OkHttpClient okHttpClient() {
        if (timeout == null) {
            log.warn("项目未配置[application.http-timeout]参数,默认5秒超时");
            timeout = 5;
        }

        return new OkHttpClient().newBuilder()
                // 设置读取超时时间
                .readTimeout(timeout, TimeUnit.SECONDS)
                // 设置写的超时时间
                .writeTimeout(timeout, TimeUnit.SECONDS)
                // 设置连接超时时间
                .connectTimeout(timeout, TimeUnit.SECONDS)
                // 支持HTTPS
                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                .hostnameVerifier((hostname, session) -> true)
                .build();
    }

    /**
     * 创建SSL链接
     *
     * @return
     */
    @Bean
    public SSLSocketFactory sslSocketFactory() {
        SSLSocketFactory ssfFactory = null;

        try {
            // 信任任何链接
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());

            ssfFactory = sc.getSocketFactory();
        } catch (Exception e) {
            log.info("OkHttpUtil初始化SSL异常: " + TextUtil.ex2Txt(e));
        }

        return ssfFactory;
    }

    /**
     * 生成证书信任管理器
     *
     * @return
     */
    @Bean
    public X509TrustManager x509TrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
    }

}
